/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package muhnes.sizoo.seguridad;

import java.util.Calendar;
import java.util.Date;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import muhnes.sizoo.HibernateUtilLog;
import muhnes.sizoo.dal.BitacoraDao;
import muhnes.sizoo.dal.FabricaDAO;
import muhnes.sizoo.modelo.Bitacora;
import muhnes.sizoo.modelo.Usuario;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.hibernate.context.ManagedSessionContext;
import org.hibernate.event.PostDeleteEvent;
import org.hibernate.event.PostDeleteEventListener;
import org.hibernate.event.PostInsertEvent;
import org.hibernate.event.PostInsertEventListener;
import org.hibernate.event.PostUpdateEvent;
import org.hibernate.event.PostUpdateEventListener;

public class CRUDListener implements PostInsertEventListener, 
                                     PostUpdateEventListener, 
                                     PostDeleteEventListener {
    
    private SessionFactory creadorSesiones = HibernateUtilLog.getSessionFactory();

    @Override
    public void onPostInsert( PostInsertEvent evento ) {
        
        Object entidad = evento.getEntity();
        if( entidad instanceof IAuditable  ) {
            registrarAccion( "Agregar", (IAuditable)entidad );
        }
        
    }

    @Override
    public void onPostUpdate( PostUpdateEvent evento ) {
        
        Object entidad = evento.getEntity();
        if( entidad instanceof IAuditable  ) {
            registrarAccion( "Actualizar", (IAuditable)entidad );
        }
        
    }
    
    @Override
    public void onPostDelete( PostDeleteEvent evento ) {
        
        Object entidad = evento.getEntity();
        if( entidad instanceof IAuditable  ) {
            registrarAccion( "Eliminar", (IAuditable)entidad );
        }
        
    }
    
    private void registrarAccion( String accion, IAuditable entidad ) {

        FacesContext contexto = FacesContext.getCurrentInstance();
        ExternalContext externo = contexto.getExternalContext();
        HttpServletRequest request = (HttpServletRequest)externo.getRequest();
        String tablaAfectada = entidad.getNombreAuditable();
        Date fecha = Calendar.getInstance().getTime();
        Date hora = Calendar.getInstance().getTime();
        String ip = request.getRemoteAddr();
        
        BitacoraDao dao = FabricaDAO.crearBitacoraDao();
        Session sesion = (Session) dao.obtenerSesion();
        boolean sesionAbierta = sesion.getTransaction().isActive();
        if( !sesionAbierta ) {
            ManagedSessionContext.bind(sesion);
            sesion.beginTransaction();
        }
                   
        Usuario usuario = (Usuario)request.getSession().getAttribute("usuario");
        if( !sesion.contains( usuario ) ) {
            sesion.merge( usuario );
        }
        
        Bitacora registro = new Bitacora();
        registro.setUsuario( usuario );
        registro.setAccionrealizada( accion );
        registro.setTablaafectada( tablaAfectada );
        registro.setFecha( fecha );
        registro.setHora( hora );
        registro.setIp( ip );
            
        dao.guardar( registro );
        
        if( !sesionAbierta ) {
            sesion = ManagedSessionContext.unbind(creadorSesiones);
            sesion.getTransaction().commit();
        }
        
    }
    
}
